class MyCalendar {
private:
    // 这里map存的是<endTime, startTime>
    map<int, int> m;
public:
    MyCalendar() {
        
    }
    
    bool book(int startTime, int endTime) {
        // 1. 找到第一个大于startTime的endTime
        auto e = m.upper_bound(startTime);

        // 2. 如果存在并且该日程的开始时间小于即将插入的endTime，说明存在重复预订
        // 例如现在已经有了 [10, 20) 和 [25, 30)

        // 如果现在插入 [22, 28)
        // 按照上面的找到第一个大于startTime的endTime，那么e就是[25, 30)
        // 此时25 < 28，说明重复了

        // 如果现在插入 [22, 23)
        // 按照上面的找到第一个大于startTime的endTime，那么e就是[25, 30)
        // 此时25 < 23为假，说明未重复，可插入
        
        // 如果现在插入 [22, 25]
        // 按照上面的找到第一个大于startTime的endTime，那么e就是[25, 30)
        // 此时25 < 25为假，说明未重复，可插入
        // 因为题目中说明了日程可以用一对整数 startTime 和 endTime 表示，这里的时间是半开区间，即 [startTime, endTime)
        if(e != m.end() && e->second < endTime)
            return false;

        // 3. 将endTime作为键，startTime作为值插入map中
        m[endTime] = startTime;
        return true;
    }
};

/**
 * Your MyCalendar object will be instantiated and called as such:
 * MyCalendar* obj = new MyCalendar();
 * bool param_1 = obj->book(startTime,endTime);
 */